package model_layer;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Class used for managing the data passed around in a sale.
 */
public class Sale
{
	
	private int id;
	private float total_price;
	private Date sale_date;
	private float special_discount;
	private List<SaleLineItem> items;
	private Customer customer;
	private StaffMember staff_member;

	/**
	 * Instantiates a new sale.
	 */
	public Sale()
	{
		special_discount = 0;
		items = new ArrayList<SaleLineItem>();
	}

	/**
	 * Gets the id of a sale.
	 *
	 * @return the id.
	 */
	public int getId()
	{
		return id;
	}

	/**
	 * Gets the total price of a sale.
	 *
	 * @return the total price.
	 */
	public float getTotal_price()
	{
		return total_price;
	}

	/**
	 * Gets the sale date of a sale.
	 *
	 * @return the sale date.
	 */
	public Date getSale_date()
	{
		return sale_date;
	}

	/**
	 * Gets the special discount of a sale.
	 *
	 * @return the special discount.
	 */
	public float getSpecial_discount()
	{
		return special_discount;
	}

	/**
	 * Gets the items, which a part of certain sale.
	 *
	 * @return A list with all items added to the sale.
	 */
	public List<SaleLineItem> getItems()
	{
		return items;
	}

	/**
	 * Sets the id.
	 *
	 * @param id the new id.
	 */
	public void setId(int id)
	{
		this.id = id;
	}

	/**
	 * Sets the total price of a sale.
	 *
	 * @param total_price the new total price.
	 */
	public void setTotal_price(float total_price)
	{
		this.total_price = total_price;
	}

	/**
	 * Sets the sale date of a sale.
	 *
	 * @param sale_date the new sale date.
	 */
	public void setSale_date(Date sale_date)
	{
		this.sale_date = sale_date;
	}

	/**
	 * Sets the special discount for a sale.
	 *
	 * @param special_discount the new special discount
	 */
	public void setSpecial_discount(float special_discount)
	{
		this.special_discount = special_discount;
	}

	/**
	 * Sets a list of all the items in a sale.
	 *
	 * @param items the list with items
	 */
	public void setItems(List<SaleLineItem> items)
	{
		this.items = items;
	}

	/**
	 * Gets the customer.
	 *
	 * @return the customer
	 */
	public Customer getCustomer()
	{
		return customer;
	}

	/**
	 * Sets the customer.
	 *
	 * @param customer the new customer
	 */
	public void setCustomer(Customer customer)
	{
		this.customer = customer;
	}
	
	/**
	 * Gets the Staff member.
	 *
	 * @return the staff member
	 */
	public StaffMember getStaff_member()
	{
		return staff_member;
	}

	/**
	 * Sets the staff member.
	 *
	 * @param staff_member the new staff member
	 */
	public void setStaff_member(StaffMember staff_member)
	{
		this.staff_member = staff_member;
	}

	/**
	 * Calculates the price of the sale.
	 */
	public void calculate_price()
	{
		total_price = 0;
		for (SaleLineItem item : items)
		{
			total_price += item.getPrice();
		}
		if (customer != null)
		{
			total_price *= (1 - customer.getDiscount() / 100);
		}
		total_price *= (1- special_discount / 100);
	}
	
	/**
	 * Checks for repeatition of inserted products.
	 *
	 * @param old_id the old id of a product.
	 * @param name the name
	 * @return the sale line item
	 */
	public SaleLineItem check_for_repeated_insert(String old_id, String name)
	{
		for (SaleLineItem item : items)
		{
			if(item.getProduct().getName().equals(name) && item.getProduct().getId().equals(old_id))
			{
				return item;
			}
		}
		return null;
	}
	
	/**
	 * Gets item by id.
	 *
	 * @param id the id of the item
	 * @return the item
	 */
	public SaleLineItem get_item_by_id(String id)
	{
		for(SaleLineItem item : items)
		{
			if(item.getProduct().getId().equals(id))
			{
				return item;
			}
		}
		return null;
	}
	
	/**
	 * Gets the item by name.
	 *
	 * @param name the name
	 * @return the item
	 */
	public SaleLineItem get_item_by_name(String name)
	{
		for(SaleLineItem item : items)
		{
			if(item.getProduct().getName().equals(name))
			{
				return item;
			}
		}
		return null;
	}
	
	
	/**
	 * Adds an item to the sale.
	 *
	 * @param item the item
	 */
	public void add_item(SaleLineItem item)
	{
		if(item.getProduct().getQuantity() < item.getAmount())
		{
			item.set_can_go_below_quantity(true);
		}
		items.add(item);
	}
	
	/**
	 * Updates a product.
	 *
	 * @param old_id the old id
	 * @param prod the product
	 * @return the sale line item
	 */
	public SaleLineItem update_product(String old_id, Product prod)
	{
		for(SaleLineItem item : items)
		{
			if(prod.getId().equals(item.getProduct().getId()))
			{
				return null;
			}
		}
		for (SaleLineItem item : items)
		{
			if (item.getProduct().getId().equals(old_id))
			{
				item.setProduct(prod);
				if(prod.getQuantity() < item.getAmount())
				{
					item.set_can_go_below_quantity(true);
				}
				else
				{
					item.set_can_go_below_quantity(false);
				}
				item.calculate_price();
				calculate_price();
				return item;
			}
		}
		System.err.println("Shouldn't go that far - updating product in sale");
		return null;
	}
	
	/**
	 * Updates the amount of a product.
	 *
	 * @param id the id
	 * @param amount the amount
	 * @return the sale line item
	 */
	public SaleLineItem update_amount(String id, int amount)
	{
		for(SaleLineItem item : items)
		{
			if(item.getProduct().getId().equals(id))
			{
				item.setAmount(amount);
				if(item.getProduct().getQuantity() < amount)
				{
					item.set_can_go_below_quantity(true);
				}
				else
				{
					item.set_can_go_below_quantity(false);
				}
				item.calculate_price();
				calculate_price();
				return item;
			}
		}
		System.err.println("Shouldn't go that far - update amount in sale");
		return null;
	}
	
	
	
	/**
	 * Removes a product from a sale.
	 *
	 * @param prod_id the product id
	 */
	public void remove_item(String prod_id)
	{
		for (SaleLineItem item : items)
		{
			if (item.getProduct().getId().equals(prod_id))
			{
				items.remove(item);
				break;
			}
		}
		calculate_price();
	}
	
	

}
